#pragma once
#include <sys/epoll.h>
#include <iostream>
#include "Log.hpp"
#include "Socket.hpp"
#include <set>

namespace EpollModuo{
    static const int size = 128; 
    class Epoller
    {
    public:
    Epoller(){}


    void InitEpoller(){
        _epfd = epoll_create(size);
        if(_epfd == -1)
        {
            lg.LogMessage(Fatal,"epoll_craete error %s:%d\n",strerror(errno),errno);
            exit(errno);
        }
        lg.LogMessage(Info,"epoll_craete success,epfd:%d\n",_epfd);
    }

    ~Epoller(){
        if(_epfd  >=  0)
        {
            close(_epfd);//释放epoll模型
        }
        lg.LogMessage(Info,"epoll_craete close success");
    }

    void AddEvent(int sockfd,uint32_t events)
    {
        _fd_list.insert(sockfd);


        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = sockfd;
        int n = epoll_ctl(_epfd,EPOLL_CTL_ADD,sockfd,&ev);
        if(n < 0)
        {
            lg.LogMessage(Error,"epoll_ctl add error %s:%d\n",strerror(errno),errno );
        }
    }

    int Wait(struct epoll_event* recv,int maxevents,int timeout)
    {
        return epoll_wait(_epfd,recv,maxevents,timeout);//检查是否有事件就绪
    }

    void DelEvent(int sockfd)
    {
        _fd_list.erase(sockfd);

        int n = epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);
        if(n < 0)
        {
            lg.LogMessage(Error,"epoll_ctl del error %s:%d\n",strerror(errno),errno );
        }
    }

    void DebugFdList()
    {
        std::cout << "fd list is : ";
        for(auto &fd : _fd_list)
        {
            std::cout << fd << " ";
        }
        std::cout << std::endl;
    }

    private:
        std::set<int> _fd_list;
        int _epfd;  
    };

}